﻿using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;
using Orchard.Core.Common.Utilities;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace EcoTourEduca.BingYourMaps.Models
{
    public class BingMapsAreaRecord : ContentPartRecord
    {
        public BingMapsAreaRecord()
        {
        }

        public virtual float CenterLatitude { get; set; }
        public virtual float CenterLongitude { get; set; }
        public virtual string FriendlyName { get; set; }
        public virtual int MapHeight { get; set; }
        public virtual int? MapWidth { get; set; }
        public virtual int MapZoom { get; set; }
        [StringLength(4)]
        // 4 chars is enough to identify Bing Maps mode (e.g. aerial)
        public virtual string MapType { get; set; }

        #region Operator overrides

        /// <summary>
        /// Returns true if both BingMapsAreaRecord reference in fact to the same item.
        /// </summary>
        /// <param name="areaA"></param>
        /// <param name="areaB"></param>
        /// <returns></returns>
        public static bool operator ==(BingMapsAreaRecord areaA, BingMapsAreaRecord areaB)
        {
            if (object.ReferenceEquals(areaA, areaB))
            {
                return true;
            }

            if ((object) areaA == null || (object) areaB == null)
            {
                return false;
            }

            return areaA.Id == areaB.Id;
        }

        /// <summary>
        /// Returns false when both BingMapsAreaRecord reference different items.
        /// </summary>
        /// <param name="areaA"></param>
        /// <param name="areaB"></param>
        /// <returns></returns>
        public static bool operator !=(BingMapsAreaRecord areaA, BingMapsAreaRecord areaB)
        {
            return !(areaA == areaB);
        }

        #endregion

        #region Method overrides

        /// <summary>
        /// Overrides object.Equals(). Just for good practise... calling base.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        /// <summary>
        /// Returns hash code for the BingMapsArea
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return (int) CenterLatitude ^ (int) CenterLongitude;
        }

        #endregion
    }

    public class BingMapsAreaPart : ContentPart<BingMapsAreaRecord>
    {
        #region Record mapping properties

        [Required]
        public float CenterLatitude
        {
            get { return Record.CenterLatitude; }
            set { Record.CenterLatitude = value; }
        }

        [Required]
        public float CenterLongitude
        {
            get { return Record.CenterLongitude; }
            set { Record.CenterLongitude = value; }
        }

        [Required]
        public string FriendlyName
        {
            get { return Record.FriendlyName; }
            set { Record.FriendlyName = value; }
        }

        [Required]
        public int MapHeight
        {
            get { return Record.MapHeight; }
            set { Record.MapHeight = value; }
        }

        public int? MapWidth
        {
            get { return Record.MapWidth; }
            set { Record.MapWidth  = value; }
        }

        [Required]
        public string MapType
        {
            get { return Record.MapType; }
            set { Record.MapType = value; }
        }

        [Required]
        public int MapZoom
        {
            get { return Record.MapZoom; }
            set { Record.MapZoom = value; }
        }

        #endregion

        #region Operator overrides

        /// <summary>
        /// Returns true if both BingMapsAreaPart reference in fact to the same item.
        /// </summary>
        /// <param name="areaA"></param>
        /// <param name="areaB"></param>
        /// <returns></returns>
        public static bool operator ==(BingMapsAreaPart areaA, BingMapsAreaPart areaB)
        {
            if (object.ReferenceEquals(areaA, areaB))
            {
                return true;
            }

            if ((object) areaA == null || (object) areaB == null)
            {
                return false;
            }

            return areaA.Id == areaB.Id;
        }

        /// <summary>
        /// Returns false when both BingMapsAreaPart reference different items.
        /// </summary>
        /// <param name="areaA"></param>
        /// <param name="areaB"></param>
        /// <returns></returns>
        public static bool operator !=(BingMapsAreaPart areaA, BingMapsAreaPart areaB)
        {
            return !(areaA == areaB);
        }

        #endregion

        #region Method overrides

        /// <summary>
        /// Overrides object.Equals(). Just for good practise... calling base.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }

        /// <summary>
        /// Returns hash code for the BingMapsAreaPart
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return (int) CenterLatitude ^ (int) CenterLongitude;
        }

        #endregion

        #region BingMapsLocationPart associations

        //private readonly LazyField<IEnumerable<BingMapsLocationPart>> _bingMapsLocations 
        //    = new LazyField<IEnumerable<BingMapsLocationPart>>();
        //public LazyField<IEnumerable<BingMapsLocationPart>> BingMapsLocationsField
        //{
        //    get
        //    {
        //        return _bingMapsLocations;
        //    }
        //}

        private IEnumerable<BingMapsLocationPart> _bingMapsLocations;
        public IEnumerable<BingMapsLocationPart> BingMapsLocations
        {
            get 
            {
                if (_bingMapsLocations == null)
                {
                    _bingMapsLocations = new List<BingMapsLocationPart>();
                }
                return _bingMapsLocations; 
            }
            set { _bingMapsLocations = value; }
        }

        #endregion
    }
}